package com.bnz.service.impl;

import com.alibaba.fastjson.JSON;
import com.bnz.client.ManagerClient;
import com.bnz.entity.ItemEntity;
import com.bnz.entity.TbOrderItem;
import com.bnz.entity.group.Cart;
import com.bnz.service.CartService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class CartServiceImpl implements CartService {

    /**
     * RedisTemplate和StringRedisTemplate的区别：
     * 1. 两者的关系是StringRedisTemplate继承RedisTemplate。
     *
     * 2. 两者的数据是不共通的；也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据，RedisTemplate只能管理RedisTemplate中的数据。
     *
     * 3. SDR默认采用的序列化策略有两种，一种是String的序列化策略，一种是JDK的序列化策略。
     *
     * StringRedisTemplate默认采用的是String的序列化策略，保存的key和value都是采用此策略序列化保存的。
     *
     * RedisTemplate默认采用的是JDK的序列化策略，保存的key和value都是采用此策略序列化保存的。
     */

    // 引入redis
    @Autowired
    private StringRedisTemplate redisTemplate;

    // 引入远程调用的接口(调用根据sku商品id查询数据)
    @Autowired
    private ManagerClient managerClient;

    // 1、将商品添加到购物车
    @Override
    // sellerId:sku商品id  num:购买的商品数量  name:登录的用户名
    public List<Cart> addCart(String name, String sellerId, int num) {
        // 1.1、用远程调用去查询数据  根据sku商品id查询出sku商品对象
        ItemEntity byId = managerClient.findById(sellerId);
        // 1.2、从redis中取得购物车列表(根据用户名去取sku的商品列表)
        String cartListStr = redisTemplate.opsForValue().get(name); // 购物车列表的字符串行式
        // 1.3、得到购物车列表
        // 以校验三种情况：是否为null、是否为""、是否为空字符串(引号中间有空格)" "、制表符、换行符、换页符和回车。
        if(!StringUtils.isBlank(cartListStr)){
            cartListStr = "[]";
        }
        // 1.4、转换格式
        // 将cartListStr这个json字符串中的数据，参照Cart这个类，将json字符串转换成一个一个的实体类，存入到list集合中去
        List<Cart> cartList = JSON.parseArray(cartListStr, Cart.class);
        // 1.5、根据sellerId(sku商品id)在购物车列表中查询是否有对应的购物车
        Cart cart = findCartBySellerId(cartList,byId.getSellerId());
        // 1.6、如果查到有，就将商品添加进去；不存在，就创建一个购物车，并将商品添加进去
        if (cart == null){ // 空则表示没有该购物车
            // 1.6.1、创建新的购物车
            cart = createCart(byId,num); // 购物车中有根据sellerId查出的商品对象（商家信息），数量
            // 1.6.2、将此购物车添加到购物车列表中
            cartList.add(cart);
        }else {  // 有此商家的购物车
            // 1.7、判断这个商品是否存在于此购物车  TbOrderItem:订单项的实体类
            TbOrderItem orderItem = findOrderItem(byId,cart.getOrderItemList());
            // 1.7.1、如果存在，就对它的数量和小计进行修改

        }
    }


    // 2、根据sellerId查询是否有对应的购物车（1.5创建）  cartList:购物车列表
    private Cart findCartBySellerId(List<Cart> cartList, String sellerId) {
        // 2.1、对购物车列表进行遍历
        for (Cart cart : cartList) {
            // 2.1.1、如果前端传的sellerId和购物车中的商家id一样 就返回
            if (sellerId.equals(cart.getSellerId())){
                return cart;
            }
        }
        return null;
    }

    // 3、创建的新购物车（1.6.1） 购物车有Cart实体类中的所有属性
    private Cart createCart(ItemEntity byId, int num) {
        // 3.1、创建一个新的购物车对象 cart有：商家id 商家名称 订单项列表（商品信息）
        Cart cart = new Cart();
        cart.setSellerId(byId.getSellerId()); // 商家id
        cart.setSellerName(byId.getSeller()); // 商家名称
        // 3.2、购买的商品列表对象
        List<TbOrderItem> orderItems = new ArrayList<>();
        // 3.3、根据byId对象创建TbOrderItem对象 (购物项:商品的全部信息+数量)
        TbOrderItem orderItem = createOrderItem(byId,num);
        // 3.4、向购物项列表集合添加商品(已购买的)
        orderItems.add(orderItem);
        // 3.5、将上面发购物项集合复制给cart对象中的购物项（购物车对象）
        cart.setOrderItemList(orderItems);
        // 3.6、返回购物车
        return cart;
    }


    // 4、根据itemId，查询是否有此商品  itemId==前端传的(客户选择的商品)sellerId  (1.7)
    private TbOrderItem findOrderItem(ItemEntity byId, List<TbOrderItem> orderItemList) {
        // 4.1、遍历购物项
        for (TbOrderItem orderItem : orderItemList) {
            //todo
        }
        return null;
    }

    // 5、创建的购物项（3.3创建）
    private TbOrderItem createOrderItem(ItemEntity byId, int num) {
        // 5.1、创建购物项对象
        TbOrderItem orderItem = new TbOrderItem();
        // 5.2、为购物项对象各属性复制
        orderItem.setItemId(byId.getId()); // 商品id
        orderItem.setNum(byId.getNum());  // 商品数量
        orderItem.setPrice(byId.getPrice()); // 商品单价
        orderItem.setSellerId(byId.getSellerId());  // 商家id
        orderItem.setTitle(byId.getTitle()); // 商品标题
        orderItem.setPicPath(byId.getImage()); // 商品图片
        orderItem.setTotalFee(byId.getPrice().multiply(new BigDecimal(num))); // 小计
        // 5.3、返回购物项对象（已经设置好了值）
        return orderItem;
    }
}
